//
//  HomeTableViewController.swift
//  SinaMicroBlog
//
//  Created by wxy on 15/9/1.
//  Copyright © 2015年 wxy. All rights reserved.
//

import UIKit
import SVProgressHUD

// MVVM中控制器/视图 不能直接引用模型
class HomeTableViewController: BaseTableViewController {
    
    // 微博列表数据模型
    private lazy var statusesListViewModel = StatusesListViewModel()

    override func viewDidLoad() {
       
        super.viewDidLoad()
        
        if !UserAccountViewModel.sharedUserAccount.userLogin {
            
            // 未登录显示
            vistorView?.setUpInfo(nil, message: "关注一些人，回这里看看有什么惊喜")
            
            return
        }
        
        prepareTableView()
        
        loadData()
        
    }
    
    private func prepareTableView() {
        
        // 注册原创微博cell
        tableView.registerClass(StatusesNormalCell.self, forCellReuseIdentifier: StatusesNormalCellID)
        // 注册转发微博cell
        tableView.registerClass(StatusesRepostCell.self, forCellReuseIdentifier: StatusesRepostCellID)
        
        // 自动处理行高
        tableView.estimatedRowHeight = 200
        // 不使用自动计算行高UITableViewAutomaticDimension 一定不能设置底部约束
        // tableView.rowHeight = UITableViewAutomaticDimension
        
        //取消分割线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        
        // 准备下拉刷新控件 刷新控件的高度为60
        refreshControl = RefreshControl()
        refreshControl?.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
        
        // 准备上拉刷新控件 添加到
        tableView.tableFooterView = pullUpView

    }
    
    //加载数据
    func loadData() {
        
        // 只会播放刷新动画 不会加载数据 可用于登陆第一次加载数据 好的用户体验
        refreshControl?.beginRefreshing()
        
        statusesListViewModel.loadStatuses(isPullUpResfresh: pullUpView.isAnimating()).subscribeNext({ (result) -> Void in
            
            
            // 使用 RAC 传递的数值 是 NSNumber 形式传递的
            
            let count = (result as! NSNumber).integerValue
            // 显示提示刷新微博数目
            self.showPullDownTips(count)
            
            }, error: { (error) -> Void in
                
                printLog(error)
                
                // 关闭刷新控件
                self.endLoadData()
                
                SVProgressHUD.showInfoWithStatus("您的网络不给力")
                
            }) { () -> Void in
                
                // 关闭刷新控件
                self.endLoadData()
                
                //刷新表格
                self.tableView.reloadData()
        }
    }
    
    // 显示下拉条数
    // NavBar TabBar ToolBar 不能使用自动布局
    // 不要疯狂下拉刷新 容易403
    private func showPullDownTips(count: Int) {
        
        let title = count == 0 ? "没有刷新微博" : "刷新到 \(count) 条微博"
        
        let height: CGFloat = 44
        
        // 初始提示标签在屏幕外两个高度地方 使其不能被看见
        let rect = CGRect(x: 0, y: -2 * height, width: UIScreen.mainScreen().bounds.width, height: height)
        
        pullDownTipLabel.text = title
        pullDownTipLabel.frame = rect
        
        UIView.animateWithDuration(1.2, animations: { () -> Void in
            
            // 将屏幕外的提示标签移动三个高度到导航栏下面 使其可见
            self.pullDownTipLabel.frame = CGRectOffset(rect, 0, 3 * height)
            }) { (_) -> Void in
                
                // 尾随闭包
                UIView.animateWithDuration(1.2) {
                    
                    self.pullDownTipLabel.frame = rect
                }
        }
    }
    
    // 结束刷新数据
    private func endLoadData() {
        
        // 关闭刷新控件
        self.refreshControl?.endRefreshing()
        // 关闭上拉刷新动画
        self.pullUpView.stopAnimating()
    }
    
    
    // MARK: - 懒加载控件
    // 下拉提示标签
    private lazy var pullDownTipLabel: UILabel = {
        
        let tipLabel = UILabel(title: nil, color: UIColor.whiteColor(), fontSize: 18)
        tipLabel.backgroundColor = UIColor.orangeColor()
        tipLabel.textAlignment = NSTextAlignment.Center
        
        self.navigationController?.navigationBar.insertSubview(tipLabel, atIndex: 0)
        // iOS 7 之后自动渲染默认开启 关闭之后 导航栏变成不透明
        self.navigationController?.navigationBar.translucent = false
        
        return tipLabel
    }()
    
    // 上拉刷新视图
    private lazy var pullUpView: UIActivityIndicatorView = {
        
        let indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
        indicator.color = UIColor.darkGrayColor()
        
        return indicator
    }()
}

// 类似OC分类 同时可以将遵守的协议方法 分离出来
extension HomeTableViewController {
    
    // 1.数据行数
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return statusesListViewModel.statuses.count
    }
    
    // 2.cell
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        /// 1. dequeueReusableCellWithIdentifier:indexPath 一定会返回一个cell，必须注册可重用cell
        /// 注册：registerClass/registerNib(XIB)/在 SB 中指定
        /// 如果缓冲区 cell 不存在，会使用原型 cell 实例化一个新的 cell
        /// 2. dequeueReusableCellWithIdentifier，会查询可重用cell，如果注册原型cell，能够查询到，否则，返回 nil
        /// 需要后续判断 if (cell == nil) ，是在 iOS 5.0 开发使用的
        /// 使用预估行高的时候 会先进到这里 然后取可重用cell的时候 同时获得行高
        
        // 1.获取微博数据
        let viewModel = statusesListViewModel.statuses[indexPath.row]
        
        // 2.取可重用cell
        let cell = tableView.dequeueReusableCellWithIdentifier(viewModel.reuseCellID, forIndexPath: indexPath) as! StatusesCell // 多态 父类指针指向子类对象 不影响配图cell
        
        // 3.设置数据
        cell.statusesViewModel = viewModel
        
        // 4.判断当前的 indexPath 是否是数组的最后一项 如果是 开始上拉动画 用户体验好
        if (indexPath.row == statusesListViewModel.statuses.count - 1) && !pullUpView.isAnimating() {
            
            printLog("显示上拉视图")
            pullUpView.startAnimating()
            
            // 开始刷新数据
            loadData()
        }
        
        // 5.返回cell
        return cell
    }
    
    /**
    默认情况下，会计算所有行的行高，原因：UITableView继承自 UIScrollView
    
    UIScrollView 的滚动依赖于 contentSize -> 把所有行高都计算出来，才能准确的知道 contentSize
    
    如果设置了预估行高，会根据预估行高，来计算需要显示行的尺寸！
    
    提示：如果行高是固定的，千万不要实现此代理方法！行高的代理方法，在每个版本的 Xcode 和 iOS 模拟器上执行的频率都不一样
    
    苹果在底层一直在做优化！
    
    需要行高的缓存！`只计算一次！有一个地方能够记录当前的行高！
    */

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        
        // printLog(indexPath)
        
        // 1.获取模型
        let viewModel = statusesListViewModel.statuses[indexPath.row]
          
        if viewModel.rowHeight > 0 {
            
            // printLog("缓存行高")
            return viewModel.rowHeight
        }
        
        // 2.获得cell
        let cell = tableView.dequeueReusableCellWithIdentifier(viewModel.reuseCellID) as! StatusesCell
        
        viewModel.rowHeight = cell.rowHeight(viewModel)
        
        // 3.返回行高
        return viewModel.rowHeight
        
    }
}
